//#include <REGX52.H>

#include "global.h"
#include "OneWire.h"
#include "DS18B20.h"
#include "Timer0.h"

//DS18B20指令
#define DS18B20_SKIP_ROM			0xCC
#define DS18B20_CONVERT_T			0x44
#define DS18B20_READ_SCRATCHPAD 	0xBE

/**
  * @brief  DS18B20开始温度变换
  * @param  无
  * @retval 无
  */
void DS18B20_ConvertT(void)
{
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_CONVERT_T);
}

/**
  * @brief  DS18B20读取温度
  * @param  无
  * @retval 温度数值
  */
float DS18B20_ReadT(void)
{
	unsigned char TLSB,TMSB;
	int Temp;
	float T;
	OneWire_Init();
	OneWire_SendByte(DS18B20_SKIP_ROM);
	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
	TLSB=OneWire_ReceiveByte();
	TMSB=OneWire_ReceiveByte();
	Temp=(TMSB<<8)|TLSB;
	T=Temp/16.0;
	return T;
}

#if 1

//引脚定义
sbit DQ=P1^4;

unsigned char TempData[4] = {2,4,0,6};	// 显示24.06℃

//void Set_TempData(unsigned char index, val)
//{
//	TempData
//}


void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

//
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}



/*------ 状态机优化版本 ------*/
//#define TEMP_READY_FLAG 0x80  // 使用PSW.F0作为标志位
int temperature_value = 0;    // 全局温度值存储
unsigned char temp_read_flag = 0;

int Get_Temperature_StateMachine() {
    static enum {INIT, CONVERT_START, WAIT_CONVERSION, READ_DATA} state = INIT;
    static unsigned long conversion_start_time;
    static unsigned int raw_temp;
	float temp = 0.0f;
    unsigned char temperature_updated = 0;  // 局部更新标志
    
    switch(state) {
        case INIT: {
            if(init_ds18b20()) {
                Write_DS18B20(0xCC);   // 跳过ROM
                Write_DS18B20(0x44);   // 启动转换
                conversion_start_time = GetSysTime();
                state = CONVERT_START;
            }
            return 0xFFFF;  // 初始化失败
        }
        
        case CONVERT_START: {
            // 非阻塞等待750ms
            if((GetSysTime() - conversion_start_time) >= 750) {
                if(init_ds18b20()) {
                    Write_DS18B20(0xCC);
                    Write_DS18B20(0xBE);  // 读暂存器
                    state = READ_DATA;
                } else {
                    state = INIT;  // 失败重试
                }
            }
            break;
        }
        
        case READ_DATA: {
            uint8_t TL = Read_DS18B20();
            uint8_t TH = Read_DS18B20();
            raw_temp = (TH << 8) | TL;
            
            // 带符号温度处理
            temp = raw_temp * 0.0625f;
            if(raw_temp & 0x8000) {  // 负数处理
                temp = -(float)((~raw_temp + 1) * 0.0625);
            }
            temperature_value = (int)(temp * 100 + 0.5);  // 四舍五入
            
            temp_read_flag |= TEMP_READY_FLAG;  // 设置标志位
            temperature_updated = 1;
            state = INIT;
            break;
        }
    }
    return temperature_updated ? temperature_value : 0xFFFF;
}

/*------ 标志位检查接口 ------*/
unsigned char IsTemperatureReady() {
    return (temp_read_flag & TEMP_READY_FLAG) ? 1 : 0;  // 检查PSW.F0标志
}

/*------ 主程序调用示例 ------*/
//void main() {
//    while(1) {
//        int temp = Get_Temperature_StateMachine();
//        if(IsTemperatureReady()) {
//            // 此处添加显示处理（如LCD显示temperature_value）
//            temp_read_flag &= ~TEMP_READY_FLAG;  // 清除标志位
//            UpdateDisplay(temperature_value); 
//        }
//        Delay_ms(100);
//    }
//}

#else
/*------ 获取温度值（返回放大100倍的整数值）------*/
int Get_Temperature() {
	
    static unsigned char TL, TH;
    static int temp;
    static float value;
	static unsigned int ConvertTime;
	
	static enum {ConvertT, ReadT} GetT_Status = ConvertT;
	
	switch()
	{
		case ConvertT: {
			if(!OneWire_Init()) {
				
				return 0xFFFF; // 初始化失败
			}
    
			OneWire_SendByte(0xCC);  // 跳过ROM
			OneWire_SendByte(0x44);  // 启动转换
			ConvertTime) = GetSysTime();	// 获取系统时间戳
			ConvertT = ReadT;
			}break;
		case ConvertT: {
			// 等待750ms，温度转换完成
			if((GetSysTime() - ConvertTime) >= 750) {
				DS18B20_Init();           // 重新初始化
				OneWire_SendByte(0xCC);
				OneWire_SendByte(0xBE);  // 读取暂存器
				
				TL = OneWire_ReceiveByte();  // 读取低字节
				TH = OneWire_ReceiveByte();   // 读取高字节
				
				// 合成16位温度数据
				temp = TH;
				temp = (temp << 8) | TL;
				
				// 处理温度数据（带符号计算）
				value = temp * 0.0625;    // 转换为实际温度[6](@ref)
				if(value < 0) value -= 0.05; // 负数修正
				else value += 0.05;       // 四舍五入处理[1](@ref)
			} else {
				
			}
			}break;
		default: {}break;
	}
    
    return (int)(value * 100); // 返回放大100倍的整数值（保留两位小数）
}


#endif